package com.rqb.redisson.util;

import org.apache.log4j.Logger;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Created by baiguantao on 2017/4/27. 分布式Redisson 实例获取 默认采用手动解锁的方式 也可以采用自动解锁方式
 */
@Component
public class DistributedRedisLock implements InitializingBean {
	private static final Logger _log = Logger.getLogger(DistributedRedisLock.class);
	@Autowired
	private RedissonClient redissonClient;
	public static Redisson redisson;
	
	/**
	 * 获取默认锁
	 */
	public static void acquireLock(String lockName) {
		RLock fairLock = redisson.getLock(lockName);
		fairLock.lock();// 手动去解锁
		_log.info("锁 - " + lockName + "获取成功");
	}
	
	/**
	 * 释放默认锁
	 */
	public static void realeaseLock(String lockName) {
		RLock fairLock = redisson.getLock(lockName);
		fairLock.unlock();
		_log.info("锁 - " + lockName + " - 释放成功");
	}
	
	/**
	 * 获取非公平锁
	 * @param lockName
	 * @param time 多长后自动解锁（单位：分）
	 */
	public static void acquireLockMinute(String lockName, long time) {
		RLock fairLock = redisson.getLock(lockName);
		fairLock.lock(2, TimeUnit.MINUTES);
		_log.info("锁 - " + lockName + "获取成功");
	}
	
	/**
	 * 获取公平锁
	 */
	public static void acquireFairLock(String lockName) {
		RLock fairLock = redisson.getFairLock(lockName);
		fairLock.lock();
	}

	/**
	 * 释放公平锁
	 */
	public static void realeaseFairLock(String lockName) {
		RLock fairLock = redisson.getFairLock(lockName);
		fairLock.unlock();
	}

	/**
	 * 获取读写锁 true 是读锁
	 */
	public static void acquireReadWrite(String lockName, boolean isRead) {
		RReadWriteLock rwlock = redisson.getReadWriteLock(lockName);
		if (isRead) {
			rwlock.readLock().lock();
			// rwlock.readLock().lock(10, TimeUnit.SECONDS);
		} else {
			rwlock.writeLock().lock();
			// rwlock.writeLock().lock(10, TimeUnit.SECONDS);
		}
		_log.error("======lock======" + Thread.currentThread().getName());
	}

	/**
	 * 释放读写锁 true 是读锁
	 */
	public static void releaseReadWrite(String lockName, boolean isRead) {
		RReadWriteLock rwlock = redisson.getReadWriteLock(lockName);
		if (isRead) {
			rwlock.readLock().unlock();

		} else {
			rwlock.writeLock().unlock();
		}
		_log.error("======lock======" + Thread.currentThread().getName());
	}

    /**
	 * 存入分布式set对象中
	 * @param name
	 * @param value
	 * @return
	 */
	public static RSet<String> setSet(String name, String value){
		RSet<String> set = redisson.getSet(name);
		set.add(value);
		return  set;
	}

    /**
	 * 检查分布式对象是否存在
	 * @param name
	 * @return
	 */
	public static Boolean existSet(String name){
		RSet<String> set = redisson.getSet(name);
		if (!set.isEmpty()) {
			return  true;
		}
		return  false;
	}
	@Override
	public void afterPropertiesSet() throws Exception {
		redisson = (Redisson) redissonClient;
		_log.info(redisson.getConfig().toJSON());
	}

	public static void main(String[] args) {
		String lockname="lockname";
		DistributedRedisLock.acquireLock(lockname);
		try {
			//不存在设置到redis
			if (!DistributedRedisLock.existSet(lockname)) {
				DistributedRedisLock.setSet(lockname, "1111");
				//业务逻辑begin
			} else {
				//redis中有则不处理业务逻辑
			}
		}finally {
			DistributedRedisLock.realeaseLock(lockname);
		}
	}

}
